﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Security.Permissions;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace JsonEditor.Common
{
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class PopupEditor : UITypeEditor
    {
        public PopupEditor()
        {
        }
        //下拉式还是弹出式
        public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }

        // 为属性显示UI编辑框
        public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            //值类型不为double，直接返回value
            //if (value.GetType() != typeof(int) && value.GetType() != typeof(float) && value.GetType() != typeof(double) && value.GetType() != typeof(decimal))
            //    return value;

            //值为double，显示下拉式或弹出编辑框
            IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (edSvc == null)
                return value;

            if (value.GetType() == typeof(int) || value.GetType() == typeof(float) || value.GetType() == typeof(double) || value.GetType() == typeof(decimal))
            {
                NumericUpDown ctrl = new NumericUpDown
                {
                    DecimalPlaces = 2,
                    Maximum = 100000000,
                    Value = Convert.ToDecimal(value)
                };
                edSvc.DropDownControl(ctrl);
                // 返回编辑框中编辑的值.
                return ctrl.Value;
            }
            if (value.GetType() == typeof(DateTime))
            {
                DateTimePicker ctrl = new DateTimePicker
                {
                    Format = DateTimePickerFormat.Custom,
                    Value = DateTime.Now
                };
                edSvc.DropDownControl(ctrl);
                // 返回编辑框中编辑的值.
                return ctrl.Value;
            }
            if (value.GetType() == typeof(List<object>))
            {
                
            }
            if (value.GetType() == typeof(double))
            {
                //// 显示编辑框并初始化编辑框的值
                //AngleControl angleControl = new AngleControl((double)value);
                //edSvc.DropDownControl(angleControl);
                //// 返回编辑框中编辑的值.
                //if (value.GetType() == typeof(double))
                //    return angleControl.angle;
            }
            TextBox textBox = new TextBox
            {
                Text = value.ToString()
            };
            edSvc.DropDownControl(textBox);
            return value;
        }

        //下面两个函数是为了在PropertyGrid中显示一个辅助的效果
        //可以不用重写
        public override void PaintValue(PaintValueEventArgs e)
        {
            //int normalX = (e.Bounds.Width / 2);
            //int normalY = (e.Bounds.Height / 2);

            //e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
            //e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.Width - 3, e.Bounds.Height - 3);
            //e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX + e.Bounds.X - 1, normalY + e.Bounds.Y - 1, 3, 3);

            //double radians = ((double)e.Value * Math.PI) / (double)180;
            //e.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y,
            //    e.Bounds.X + (normalX + (int)((double)normalX * Math.Cos(radians))),
            //    e.Bounds.Y + (normalY + (int)((double)normalY * Math.Sin(radians))));
        }

        public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)
        {
            return true;
        }
    }

    // 这里是我们要显示出来的编辑器，把它作为一个内置类
    //从UserControl继承，要在上面EditValue函数中使用的
    internal class AngleControl : System.Windows.Forms.UserControl
    {
        public double angle; //编辑的角度
        private float x;     //鼠标位置
        private float y;

        public AngleControl(double initial_angle)
        {
            this.angle = initial_angle;
        }
        //显现时，显示属性的当前值
        protected override void OnLoad(EventArgs e)
        {
            int originX = (this.Width / 2);
            int originY = (this.Height / 2);
            this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);
            this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);
            base.OnLoad(e);
        }

        //绘制控件，用来显示编辑角度
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            int originX = (this.Width / 2);
            int originY = (this.Height / 2);

            e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);
            e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);

            e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);
        }
        //鼠标移动时设置角度
        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int originX = (this.Width / 2);
                int originY = (this.Height / 2);
                double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));
                double h = e.Y - originY;
                this.angle = Math.Asin(h / len);
                if ((e.X >= originX && e.Y >= originY))
                {
                    this.x = (float)(50 * Math.Cos(this.angle) + originX);
                    this.y = (float)(50 * Math.Sin(this.angle) + originY);
                    this.angle = this.angle * 180 / Math.PI;
                }
                else if (e.X < originX && e.Y > originY)
                {
                    this.x = (float)(originX - 50 * Math.Cos(this.angle));
                    this.y = (float)(50 * Math.Sin(this.angle) + originY);
                    this.angle = 180 - this.angle * 180 / Math.PI;
                }
                else if (e.X < originX && e.Y < originY)
                {
                    this.x = (float)(originX - 50 * Math.Cos(this.angle));
                    this.y = (float)(originY + 50 * Math.Sin(this.angle));
                    this.angle = 180 - this.angle * 180 / Math.PI;
                }
                else if (e.X >= originX && e.Y <= originY)
                {
                    this.x = (float)(originX + 50 * Math.Cos(this.angle));
                    this.y = (float)(originY + 50 * Math.Sin(this.angle));
                    this.angle = 360 + this.angle * 180 / Math.PI;
                }
                this.Invalidate();
            }

        }
    }
}
